package avicti.bdp.das;

import avicit.bdp.common.database.ColumnMeta;
import avicit.bdp.common.database.TableMeta;
import avicit.bdp.common.datasource.BaseDataSource;
import avicit.bdp.common.service.dto.BdpColumnDTO;
import avicit.bdp.common.service.dto.BdpTableDTO;
import avicit.bdp.common.service.dto.DataSourceDTO;
import avicit.bdp.common.service.service.DataSourceService;
import avicit.bdp.common.utils.database.DBUtils;
import avicit.bdp.common.utils.database.adapter.DbAdapter;
import avicit.bdp.common.utils.database.adapter.DbAdapterUtils;
import avicit.bdp.dms.DmsApplication;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = DmsApplication.class)
public class DbAdapterTest {

    @Autowired
    private static DataSourceService dataSourceService;
    private static DbAdapter adapter;
    private static BdpTableDTO dataTable;
    private static DataSourceDTO dataSourceDTO;
    private static BaseDataSource dbSource;
    private static ColumnMeta columnMeta;
    private static TableMeta tableMeta;
    private static Connection connection;

    private static final String dataSourceId = "4028809875f40ca10175f40ca1d20000";

    @Autowired
    public void setDataSourceService(DataSourceService dataSourceService) {
        this.dataSourceService = dataSourceService;
    }

    @Before
    public void setUp() throws Exception {
        Assert.assertNotNull(dataSourceService);

        dataSourceDTO = dataSourceService.selectByPrimaryKey(dataSourceId);
        Assert.assertNotNull(dataSourceDTO);

        dbSource = DBUtils.getBaseDataSource(dataSourceDTO);

        adapter = DbAdapterUtils.getDbAdapter(dataSourceDTO.getDatasourceType());
        Assert.assertNotNull(adapter);

        dataTable = createIotDbDataTable();
        columnMeta = createColumn();

        dataTable.setBdpDasDatasourceDTO(dataSourceDTO);

        connection = DBUtils.buildConnection(dataSourceDTO);
        Assert.assertNotNull(connection);

        tableMeta = new TableMeta();
        BeanUtils.copyProperties(dataTable, tableMeta);
    }

    /**
     * createDataTable
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void createDataTable() throws Exception {
        Assert.assertNotNull(connection);
        adapter.createDataTable(tableMeta, connection);
    }

    /**
     * dropDataTable
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void dropDataTable() throws Exception {
        Assert.assertNotNull(connection);
    }

    /**
     * createDataColumn
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void createDataColumn() throws Exception {
        Assert.assertNotNull(connection);
        adapter.createDataColumn(connection, tableMeta, columnMeta);
    }

    /**
     * dropDataColumn
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void dropDataColumn() throws Exception {
        Assert.assertNotNull(connection);
        adapter.dropDataColumn(connection, tableMeta, columnMeta);
    }

    /**
     * isExistTable
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void isExistTable() throws Exception {
        Assert.assertNotNull(connection);
        adapter.isExistTable(tableMeta.getName(), connection);
    }

    /**
     * isExistColumn
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void getDataTable() throws Exception {
        Assert.assertNotNull(dataSourceDTO);
        //获取表
        List<TableMeta> tableMetaList = adapter.getDataTable(dbSource,false);
        for (TableMeta tableMeta : tableMetaList) {
            System.out.println(tableMeta);
        }
    }

    /**
     * get version
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void getVersion() throws Exception {
        //获取表
        Assert.assertNotNull(dataSourceDTO);
        BaseDataSource baseDataSource = DBUtils.getBaseDataSource(dataSourceDTO);
        Assert.assertNotNull(baseDataSource);

        String version = adapter.getVersion(baseDataSource);
        Assert.assertNotNull(version);
    }

    /**
     * get version
     *
     * @throws Exception e
     */
    @Test(timeout = 60 * 1000)
    public void getOtherCount() throws Exception {
        //获取表
        Assert.assertNotNull(dataSourceDTO);
        long count = adapter.getOtherCount(dataSourceDTO);
        Assert.assertNotNull(count);
    }


    @Test(timeout = 60 * 1000)
    public void getTableDataListFromDb() throws Exception {
        Assert.assertNotNull(dataSourceDTO);
        BaseDataSource baseDataSource = DBUtils.getBaseDataSource(dataSourceDTO);
        Map<String, Object> paramsMap = new HashMap<>(2);
        paramsMap.put("isLowerKey", "1");
        String sql = "select * from " + dataTable.getName();
        Map<String, Object> data = adapter.getTableDataListFromDb(baseDataSource, sql,
                1, 20, paramsMap);
        System.out.println(data);
    }

    private static ColumnMeta createColumn() {
        ColumnMeta columnMeta = new ColumnMeta();
        columnMeta.setName("name");
        columnMeta.setColumnType("varchar");
        columnMeta.setColumnLength(10);
        return columnMeta;
    }


    private static BdpTableDTO createIotDbDataTable() {
        BdpTableDTO dataTable = new BdpTableDTO();
        dataTable.setStorageGroup("root.ma");
        dataTable.setName("root.ma.test");

        List<BdpColumnDTO> columns = new ArrayList<>();
        dataTable.setColumnList(columns);

        BdpColumnDTO c1 = new BdpColumnDTO();
        c1.setName("name");
        c1.setColumnType("varchar");
        c1.setColumnLength(10);

        BdpColumnDTO c2 = new BdpColumnDTO();
        c2.setName("age");
        c2.setColumnType("int");
        c2.setColumnLength(10);

        columns.add(c1);
        columns.add(c2);

        return dataTable;
    }


    /**
     * 单个测试用例运行后销毁工作
     */
    @After
    public void tearDown() {

    }

    /**
     * 所有用例执行完成后准备工作
     */
    @AfterClass
    public static void destroy() {
        DBUtils.closeResource(connection, null, null);
    }


}
